package com.xiaoq.web;

import java.nio.charset.StandardCharsets;
import java.security.KeyStore;
import java.security.cert.CertificateException;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;

import org.apache.http.client.HttpClient;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContexts;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

@Component
public class HttpsRestTemplate extends RestTemplate {
	
	private String httpsTrestStoreKey = "smartt";
	
	public HttpsRestTemplate() {
		super();
		getMessageConverters().set(1, new StringHttpMessageConverter(StandardCharsets.UTF_8));
	}
	
	@PostConstruct
	public void initTrustStore() {
		try {
			KeyStore trustStore = KeyStore.getInstance("JKS");
			Resource fileRource = new ClassPathResource("smartt.truststore");
			trustStore.load(fileRource.getInputStream(), httpsTrestStoreKey.toCharArray());
			TrustStrategy ts = new TrustStrategy() {
				@Override
				public boolean isTrusted(java.security.cert.X509Certificate[] chain, String authType)
						throws CertificateException {
					return true;
				}
			};
			
			SSLContext sslContext = SSLContexts.custom()
					.loadTrustMaterial(trustStore, ts)
					.build();
			
			SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(
					sslContext,
					new HostnameVerifier(){
						@Override
						public boolean verify(String hostname, SSLSession session) {
							return true;
						}
					});
			
			HttpClient httpClient = HttpClients.custom().setSSLSocketFactory(socketFactory).build();
			
			ClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(httpClient);
			this.setRequestFactory(requestFactory);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public HttpsRestTemplate(ClientHttpRequestFactory requestFactory) {
		super(requestFactory);
	}
	
	public HttpsRestTemplate(List<HttpMessageConverter<?>> messageConverters) {
		super(messageConverters);
	}
	
}
